home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sndhrdw / polepos.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  5KB  |  182 lines

  1. /***************************************************************************
  2.     polepos.c
  3.     Sound handler
  4. ****************************************************************************/
  5. #include "driver.h"
  6.  
  7. static int sample_msb = 0;
  8. static int sample_lsb = 0;
  9. static int sample_enable = 0;
  10.  
  11. static int current_position;
  12. static int sound_stream;
  13.  
  14. /* speech section */
  15. static int channel;
  16. static INT8 *speech;
  17. /* macro to convert 4-bit unsigned samples to 8-bit signed samples */
  18. #define SAMPLE_CONV4(a) (0x11*((a&0x0f))-0x80)
  19. #define SAMPLE_SIZE 0x8000
  20.  
  21. #define AMP(r)    (r*128/10100)
  22. static int volume_table[8] =
  23. {
  24.     AMP(2200), AMP(3200), AMP(4400), AMP(5400),
  25.     AMP(6900), AMP(7900), AMP(9100), AMP(10100)
  26. };
  27. static int sample_offsets[4];
  28.  
  29. /************************************/
  30. /* Stream updater                   */
  31. /************************************/
  32. static void engine_sound_update(int num, INT16 *buffer, int length)
  33. {
  34.     UINT32 current = current_position, step, clock, slot, volume;
  35.     UINT8 *base;
  36.  
  37.  
  38.     /* if we're not enabled, just fill with 0 */
  39.     if (!sample_enable || Machine->sample_rate == 0)
  40.     {
  41.         memset(buffer, 0, length * sizeof(INT16));
  42.         return;
  43.     }
  44.  
  45.     /* determine the effective clock rate */
  46.     clock = (Machine->drv->cpu[0].cpu_clock / 64) * ((sample_msb + 1) * 64 + sample_lsb + 1) / (16*64);
  47.     step = (clock << 12) / Machine->sample_rate;
  48.  
  49.     /* determine the volume */
  50.     slot = (sample_msb >> 3) & 7;
  51.     volume = volume_table[slot];
  52.     base = &memory_region(REGION_SOUND1)[0x1000 + slot * 0x800];
  53.  
  54.     /* fill in the sample */
  55.     while (length--)
  56.     {
  57.         *buffer++ = (base[(current >> 12) & 0x7ff] * volume);
  58.         current += step;
  59.     }
  60.  
  61.     current_position = current;
  62. }
  63.  
  64. /************************************/
  65. /* Sound handler start              */
  66. /************************************/
  67. int polepos_sh_start(const struct MachineSound *msound)
  68. {
  69.     int i, bits, last=0;
  70.  
  71.     channel = mixer_allocate_channel(25);
  72.     mixer_set_name(channel,"Speech");
  73.  
  74.     speech = malloc(16*SAMPLE_SIZE);
  75.     if (!speech)
  76.         return 1;
  77.  
  78.     /* decode the rom samples, interpolating to make it sound a little better */
  79.     for (i = 0;i < SAMPLE_SIZE;i++)
  80.     {
  81.         bits = memory_region(REGION_SOUND1)[0x5000+i] & 0x0f;
  82.         bits = SAMPLE_CONV4(bits);
  83.         speech[16*i+0] = (7 * last + 1 * bits) / 8;
  84.         speech[16*i+1] = (6 * last + 2 * bits) / 8;
  85.         speech[16*i+2] = (5 * last + 3 * bits) / 8;
  86.         speech[16*i+3] = (4 * last + 4 * bits) / 8;
  87.         speech[16*i+4] = (3 * last + 5 * bits) / 8;
  88.         speech[16*i+5] = (2 * last + 6 * bits) / 8;
  89.         speech[16*i+6] = (1 * last + 7 * bits) / 8;
  90.         speech[16*i+7] = bits;
  91.         last = bits;
  92.  
  93.         bits = (memory_region(REGION_SOUND1)[0x5000+i] & 0xf0) >> 4;
  94.         bits = SAMPLE_CONV4(bits);
  95.         speech[16*i+8] = (7 * last + 1 * bits) / 8;
  96.         speech[16*i+9] = (6 * last + 2 * bits) / 8;
  97.         speech[16*i+10] = (5 * last + 3 * bits) / 8;
  98.         speech[16*i+11] = (4 * last + 4 * bits) / 8;
  99.         speech[16*i+12] = (3 * last + 5 * bits) / 8;
  100.         speech[16*i+13] = (2 * last + 6 * bits) / 8;
  101.         speech[16*i+14] = (1 * last + 7 * bits) / 8;
  102.         speech[16*i+15] = bits;
  103.         last = bits;
  104.     }
  105.  
  106.     /* Japanese or US PROM? */
  107.     if (memory_region(REGION_SOUND1)[0x5000] == 0)
  108.     {
  109.         /* US */
  110.         sample_offsets[0] = 0x0020;
  111.         sample_offsets[1] = 0x0c00;
  112.         sample_offsets[2] = 0x1c00;
  113.         sample_offsets[3] = 0x2000;
  114.         sample_offsets[4] = 0x2000;
  115.     }
  116.     else
  117.     {
  118.         /* Japan */
  119.         sample_offsets[0] = 0x0020;
  120.         sample_offsets[1] = 0x0900;
  121.         sample_offsets[2] = 0x1f00;
  122.         sample_offsets[3] = 0x4000;
  123.         sample_offsets[4] = 0x6000;        /* How is this triggered? */
  124.     }
  125.  
  126.     sound_stream = stream_init("Engine Sound", 50, Machine->sample_rate, 0, engine_sound_update);
  127.     current_position = 0;
  128.     sample_msb = sample_lsb = 0;
  129.     sample_enable = 0;
  130.     return 0;
  131. }
  132.  
  133. /************************************/
  134. /* Sound handler stop               */
  135. /************************************/
  136. void polepos_sh_stop(void)
  137. {
  138.     if (speech)
  139.         free(speech);
  140.     speech = NULL;
  141. }
  142.  
  143. /************************************/
  144. /* Sound handler update             */
  145. /************************************/
  146. void polepos_sh_update(void)
  147. {
  148. }
  149.  
  150. /************************************/
  151. /* Write LSB of engine sound        */
  152. /************************************/
  153. WRITE_HANDLER( polepos_engine_sound_lsb_w )
  154. {
  155.     stream_update(sound_stream, 0);
  156.     sample_lsb = data & 62;
  157.     sample_enable = data & 1;
  158. }
  159.  
  160. /************************************/
  161. /* Write MSB of engine sound        */
  162. /************************************/
  163. WRITE_HANDLER( polepos_engine_sound_msb_w )
  164. {
  165.     stream_update(sound_stream, 0);
  166.     sample_msb = data & 63;
  167. }
  168.  
  169. /************************************/
  170. /* Play speech sample                */
  171. /************************************/
  172. void polepos_sample_play(int sample)
  173. {
  174.     int start = sample_offsets[sample];
  175.     int len = sample_offsets[sample + 1] - start;
  176.  
  177.     if (Machine->sample_rate == 0)
  178.         return;
  179.  
  180.     mixer_play_sample(channel, speech + start * 16, len * 16, 4000*8, 0);
  181. }
  182.